home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / devices and hardware / disks / iso9660 / buildiso.c next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  18.6 KB  |  731 lines

  1. /*
  2.     File:        BuildISO.c
  3.     
  4.     Description:Try to build a ISO 9660 floppy disc, interactively.
  5.                  Currently only builds the Primary Volume Descriptor
  6.                 and puts files at the root level.  Does not do
  7.                 subdirectories.
  8.  
  9.     Author:        BB
  10.  
  11.     Copyright:     Copyright: © 1988-1999 by Apple Computer, Inc.
  12.                 all rights reserved.
  13.     
  14.     Disclaimer:    You may incorporate this sample code into your applications without
  15.                 restriction, though the sample code has been provided "AS IS" and the
  16.                 responsibility for its operation is 100% yours.  However, what you are
  17.                 not permitted to do is to redistribute the source as "DSC Sample Code"
  18.                 after having made changes. If you're going to re-distribute the source,
  19.                 we require that you make it clear in the source that the code was
  20.                 descended from Apple Sample Code, but that you've made changes.
  21.     
  22.     Change History (most recent first):
  23.                 6/24/99    Updated for Metrowerks Codewarror Pro 2.1(KG)
  24.                 1/94    Converted to Universal Headers.  Fixed a bug which prevented    
  25.                         Apple extensions from working correctly.
  26.                 5/90    Modified for d e v e l o p and Think C 4.0
  27.                 7/1/88    Original Version for the Macintosh(BB)
  28.  
  29. */
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. #include <string.h>
  33. #include <Files.h>
  34. #include <OSUtils.h>
  35. #include <Memory.h>
  36. #include <Errors.h>
  37. #include <strings.h>
  38. #include <Devices.h>
  39. #include <MacMemory.h>
  40.  
  41.  
  42. #include "HighSierra.h"
  43. #include "BuildISO.h"
  44.  
  45. #define    FLOPPY_SIZE    0x186        /* size in 2k blocks of a 800k floppy */
  46.  
  47. #include "ErrorMsg.h"
  48. #include "i_o.h"
  49. #include "Support.h"
  50. #include "MyDialog.h"
  51.  
  52. Str255            nullStr = "\p";
  53. Str255            rootName = "\p\000";
  54. Str255            parentName = "\p\001";
  55.  
  56. /************************************************************************
  57.  *
  58.  *  Function:        CreatePVD
  59.  *
  60.  *  Purpose:        create the contents of the Primary Volume Descriptor.
  61.  *
  62.  *  Returns:        void
  63.  *
  64.  *  Side Effects:    adds to the output file.
  65.  *
  66.  *  Description:    go through all the primary volume descriptor, showing
  67.  *                    each field in all it's glory.  We don't bother showing
  68.  *                    the extra blanks at the end of each string field.
  69.  *
  70.  *
  71.  ************************************************************************/
  72.  
  73. OSErr
  74. CreatePVD(short referenceNumber)
  75. {
  76.     PVD        p;
  77.     OSErr    result;
  78.     long    offset;
  79.     char    volID[33];
  80.     Boolean    goOn;
  81.     
  82.     ClearOut((char *)&p, sizeof(p));
  83.     p.VDType = 1;
  84.     p.VSStdId[0] = 'C';
  85.     p.VSStdId[1] = 'D';
  86.     p.VSStdId[2] = '0';
  87.     p.VSStdId[3] = '0';
  88.     p.VSStdId[4] = '1';
  89.     p.VSStdVersion = 1;
  90.     CharCopy(p.systemIdentifier, "Apple Computer, Inc., Type:0001", sizeof(p.systemIdentifier));
  91.  
  92.     goOn = AskForString((char *)"\pWhat do you want to call this volume? (32 characters or less)", volID);
  93.     if (goOn == false)
  94.         return -1;
  95.  
  96.     NormalizeVolumeName(volID);
  97.     CharCopy(p.volumeIdentifier, volID, sizeof(p.volumeIdentifier));
  98.  
  99.  
  100.     p.lsbVolumeSpaceSize = NormalizeLong((long)FLOPPY_SIZE);
  101.     p.msbVolumeSpaceSize = (long)FLOPPY_SIZE;
  102.     p.lsbVolumeSetSize = NormalizeWord(FLOPPY_SIZE);
  103.     p.msbVolumeSetSize = FLOPPY_SIZE;
  104.     p.lsbVolumeSetSequenceNumber = NormalizeWord(1);
  105.     p.msbVolumeSetSequenceNumber = 1;
  106.     
  107.     p.lsbLogicalBlockSize = NormalizeWord(CDBLKSIZE);
  108.     p.msbLogicalBlockSize = CDBLKSIZE;
  109.                 
  110.  
  111.     p.lsbPathTableSize = NormalizeLong(PATHTBLSIZE);
  112.     p.msbPathTableSize = PATHTBLSIZE;
  113.     p.lsbPathTable1 = NormalizeLong(LSBPATH);
  114.     p.msbPathTable1 = MSBPATH;
  115.     
  116.     p.lsbPathTable2 = 0L;
  117.     p.msbPathTable2 = 0L;
  118.     
  119.     /* Exercise for reader: get the time via GetTime() and convert
  120.     ** to string of the format shown below for these strange dates.
  121.     ** Use that date and time to fill the various volume date fields.
  122.     ** The date shown is my daughter's birth date and time...
  123.     */
  124.     CharCopy(p.volumeCreation, "19870914060100000", sizeof(p.volumeCreation));
  125.     CharCopy(p.volumeModification, "19870914060100000", sizeof(p.volumeModification));
  126.     CharCopy(p.volumeExpiration, "00000000000000000", sizeof(p.volumeExpiration));
  127.     CharCopy(p.volumeEffective, "19870914060100000", sizeof(p.volumeEffective));
  128.  
  129.     p.FileStructureStandardVersion = 1;
  130.     
  131.     SpaceOut(p.volumeSetIdentifier, sizeof(p.volumeSetIdentifier));
  132.     SpaceOut(p.publisherIdentifier, sizeof(p.publisherIdentifier));
  133.     SpaceOut(p.dataPreparerIdentifier, sizeof(p.dataPreparerIdentifier));
  134.     SpaceOut(p.applicationIdentifier, sizeof(p.applicationIdentifier));
  135.     SpaceOut(p.copyrightFileIdentifier, sizeof(p.copyrightFileIdentifier));
  136.     SpaceOut(p.abstractFileIdentifier, sizeof(p.abstractFileIdentifier));
  137.     SpaceOut(p.bibliographicFileIdentifier, sizeof(p.bibliographicFileIdentifier));
  138.  
  139.     CreateDirRcd((DirRcd *)&p.rootDirectoryRecord, rootName, 
  140.         DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  141.     
  142.     p.Reserved1 = 0;
  143.     ClearOut(p.Reserved2, sizeof(p.Reserved2));
  144.     ClearOut(p.Reserved3, sizeof(p.Reserved3));
  145.     p.Reserved4 = 0;
  146.  
  147. #ifdef VERBOSE    /* if I want to verify what I've done */
  148.     DumpPVD(&p);
  149. #endif
  150.     offset = (long) HSVOLSTART * (long) CDBLKSIZE;
  151.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  152.     if (result != noErr)
  153.         ErrorMsg("CreatePVD: isoWrite() returned %d", result);
  154.     else
  155.         ErrorMsg("volume descriptors successfully created.");
  156.     return result;
  157. }
  158.  
  159.  
  160. /************************************************************************
  161.  *
  162.  *  Function:        CreateVDT
  163.  *
  164.  *  Purpose:        create the contents of the Volume Descriptor Terminator
  165.  *
  166.  *  Returns:        void
  167.  *
  168.  *  Side Effects:    adds to the output file.
  169.  *
  170.  *  Description:    Build a simple VDT, fill it in, and write it out to
  171.  *                    a famous place.
  172.  *
  173.  *
  174.  ************************************************************************/
  175.  
  176. OSErr
  177. CreateVDT(short referenceNumber)
  178. {
  179.     PVD        p;
  180.     OSErr    result;
  181.     long    offset;
  182.     
  183.     ClearOut((char *)&p, sizeof(p));
  184.     p.VDType = 255;
  185.     p.VSStdId[0] = 'C';
  186.     p.VSStdId[1] = 'D';
  187.     p.VSStdId[2] = '0';
  188.     p.VSStdId[3] = '0';
  189.     p.VSStdId[4] = '1';
  190.     p.VSStdVersion = 1;
  191.     offset = (long) HSTERMSTART * (long) CDBLKSIZE;
  192.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  193.     if (result != noErr)
  194.         ErrorMsg("CreateVDT: isoWrite() returned %d", result);
  195.     return result;
  196. }
  197.  
  198.  
  199.  
  200.  
  201. /************************************************************************
  202.  *
  203.  *  Function:        CreatePathTable
  204.  *
  205.  *  Purpose:        create path tables
  206.  *
  207.  *  Returns:        nothing
  208.  *
  209.  *  Side Effects:    writes lsb path table and msb path table
  210.  *
  211.  *  Description:    We'll assume just the root.  Dump out the path
  212.  *                    path table in both formats.  We'll put the
  213.  *                    path table in famous spots.
  214.  *
  215.  ************************************************************************/
  216. OSErr
  217. CreatePathTable(short referenceNumber)
  218. {
  219.     char    buffer[CDBLKSIZE];
  220.     PathTableRecordPtr    d;
  221.     long    offset;
  222.     OSErr    result;
  223.     
  224.     ClearOut(buffer, sizeof(buffer));
  225.     d = (PathTableRecordPtr) &buffer[0];
  226.     
  227.     d->len_di = 1;
  228.     d->XARlength = 0;
  229.     d->dirLocation = NormalizeLong(DIRECTORY);
  230.     d->parentDN = 0;
  231.     
  232.     offset = LSBPATH * (long) CDBLKSIZE;
  233.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  234.     if (result != noErr)
  235.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  236.     
  237.     d->len_di = 1;
  238.     d->dirLocation = DIRECTORY;
  239.     d->parentDN = 0;
  240.     
  241.     offset = MSBPATH * (long) CDBLKSIZE;
  242.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  243.     if (result != noErr)
  244.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  245.     return result;
  246. }
  247.  
  248.  
  249. /************************************************************************
  250.  *
  251.  *  Function:    CreateDirRcd
  252.  *
  253.  *  Purpose:    Create a directory record for a file
  254.  *
  255.  *  Returns:    none
  256.  *
  257.  *  Side Effects:    fills *d with directory information.  We assume
  258.  *                    caller has allocated space for d.
  259.  *
  260.  *  Description:
  261.  *
  262.  ************************************************************************/
  263. void
  264. CreateDirRcd(DirRcd *d, StringPtr name, long start, long length, short flags, OSType fType, OSType fCreator, short finderFlags)
  265. {
  266.     Ptr        dPtr;
  267.     DateTimeRec    today;
  268.  
  269.     d->XARlength = 0;
  270.     d->lsbStart = NormalizeLong(start);
  271.     d->msbStart = start;
  272.     d->lsbDataLength = NormalizeLong(length);
  273.     d->msbDataLength = length;
  274.     d->fileFlags = flags;
  275.     if (finderFlags & fInvisible)
  276.         d->fileFlags |= existenceBit;
  277.     GetTime(&today);
  278.     d->year = today.year-1900;
  279.     d->month = today.month;
  280.     d->day = today.day;
  281.     d->hour = today.hour;
  282.     d->minute = today.minute;
  283.     d->second = today.second;
  284.     d->gmtOffset = 0;
  285.     d->interleaveSize = 0;
  286.     d->interleaveSkip = 0;
  287.     d->lsbVolSetSeqNum = NormalizeWord(1);
  288.     d->msbVolSetSeqNum = 1;
  289.     
  290.     d->len_fi = CreateISOName((char *)d->fi, name);
  291.  
  292.     d->len_dr = 32 + d->len_fi;
  293.     
  294.     AddAppleExtensions(d, fType, fCreator, finderFlags);
  295.     
  296.     if (d->len_dr & 1)    /* odd dirRcds need pad byte */
  297.     {
  298.         dPtr = (char *)d;
  299.         dPtr[d->len_dr] = '\000';
  300.         d->len_dr++;
  301.     }
  302. }
  303.  
  304.  
  305. /************************************************************************
  306.  *
  307.  *  Function:        AddOldAppleExtensions
  308.  *
  309.  *  Purpose:        optionally add apple extensions to ISO 9660
  310.  *
  311.  *  Returns:        void
  312.  *
  313.  *  Side Effects:    directory record may get extended.  Must have enough
  314.  *                    room in area pointed to by dirRcd for this to happen.
  315.  *
  316.  *  Description:    Check the fType.  If it's non-zero, add the information
  317.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  318.  *                    that we can't just assign fType and fCreator, since
  319.  *                    longs are aligned within structures.
  320.  *
  321.  *                    This procedure adds the old, "BA" Apple extensions.
  322.  *
  323.  ************************************************************************/
  324. void
  325. AddOldAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
  326. {
  327.     OldAppleExtension    apple;
  328.     short            i;
  329.     short            j;
  330.     short            limit;
  331.     char            *aPtr;
  332.     Ptr                fPtr;
  333.     
  334.     if (fType != 0L)
  335.     {
  336.         apple.macFlag[0] = 'B';
  337.         apple.macFlag[1] = 'A';
  338.         apple.systemUseID = 06;
  339.         fPtr = (char *)&fType;
  340.         
  341.         for (i = 0; i < 4; i++)
  342.             apple.fileType[i] = fPtr[i];
  343.         fPtr = (char *)&fCreator;
  344.         
  345.         for (i = 0; i < 4; i++)
  346.             apple.fileCreator[i] = fPtr[i];
  347.         
  348.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  349.         apple.finderFlags[1] = flags & 0xFF;
  350.         
  351.         limit = sizeof(apple);
  352.         
  353.         aPtr = (char *)&apple;
  354.  
  355.         j = dirRcd->len_fi;
  356.         
  357.         if (!(j & 1))        /* 9401 bug fix BL°B */
  358.         {
  359.             dirRcd->fi[j] = 0;
  360.             j++;    /* there is a pad byte after odd length file names */
  361.         }
  362.         
  363.         for (i = 0; i <= limit; i++)
  364.             dirRcd->fi[i + j] = aPtr[i];
  365.         
  366.         dirRcd->len_dr += limit;
  367.     }
  368. }    
  369.  
  370.  
  371. /************************************************************************
  372.  *
  373.  *  Function:        AddAppleExtensions
  374.  *
  375.  *  Purpose:        optionally add apple extensions to ISO 9660
  376.  *
  377.  *  Returns:        void
  378.  *
  379.  *  Side Effects:    directory record may get extended.  Must have enough
  380.  *                    room in area pointed to by dirRcd for this to happen.
  381.  *
  382.  *  Description:    Check the fType.  If it's non-zero, add the information
  383.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  384.  *                    that we can't just assign fType and fCreator, since
  385.  *                    longs are aligned within structures.
  386.  *
  387.  ************************************************************************/
  388. void
  389. AddAppleExtensions(DirRcd *dirRcd, OSType fType, OSType fCreator, short flags)
  390. {
  391.     AppleExtension    apple;
  392.     short            i;
  393.     short            j;
  394.     short            limit;
  395.     char            *aPtr;
  396.     Ptr                fPtr;
  397.     
  398.     if (fType != 0L)
  399.     {
  400.         apple.signature[0] = 'A';
  401.         apple.signature[1] = 'A';
  402.         apple.extensionLength = 0x0E;
  403.         apple.systemUseID = 02;
  404.         fPtr = (char *)&fType;
  405.         
  406.         for (i = 0; i < 4; i++)
  407.             apple.fileType[i] = fPtr[i];
  408.         fPtr = (char *)&fCreator;
  409.         
  410.         for (i = 0; i < 4; i++)
  411.             apple.fileCreator[i] = fPtr[i];
  412.         
  413.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  414.         apple.finderFlags[1] = flags & 0xFF;
  415.         
  416.         limit = sizeof(apple);
  417.         
  418.         aPtr = (char *)&apple;
  419.  
  420.         j = dirRcd->len_fi;
  421.         
  422.         if (!(j & 1))        /* 9401 bug fix BL°B */
  423.         {
  424.             dirRcd->fi[j] = 0;
  425.             j++;    /* there is a pad byte after odd length file names */
  426.         }
  427.         
  428.         for (i = 0; i <= limit; i++)
  429.             dirRcd->fi[i + j] = aPtr[i];
  430.         
  431.         dirRcd->len_dr += limit;
  432.     }
  433. }    
  434.  
  435.  
  436. /************************************************************************
  437.  *
  438.  *  Function:        CopyDirRcdToBuffer
  439.  *
  440.  *  Purpose:        copy directory record to buffer
  441.  *
  442.  *  Returns:        nothing
  443.  *
  444.  *  Side Effects:    buffer is filled a little bit more
  445.  *
  446.  *  Description:    copy a directory record to the buffer.
  447.  *
  448.  ************************************************************************/
  449. void
  450. CopyDirRcdToBuffer(DirRcd *d, char *b)
  451. {
  452.     char    *dPrime;
  453.     short    i;
  454.     
  455.     dPrime = (char *)d;
  456.     for (i = 0; i < d->len_dr; i++)
  457.         *b++ = *dPrime++;
  458. }
  459.  
  460. /************************************************************************
  461.  *
  462.  *  Function:        CopyRsrcFork
  463.  *
  464.  *  Purpose:        copy the resource fork of a file
  465.  *
  466.  *  Returns:        OSErr
  467.  *                        mostly noErr, but could be
  468.  *                        ioErr and the like if isoWrite complains.
  469.  *
  470.  *  Side Effects:    floppy gets new data written on it.
  471.  *
  472.  *  Description:    we have a starting location, "start", and a length.
  473.  *                    Allocate an appropriate buffer and read from the file
  474.  *                    specified by "name" and "vRefNum".  Write that information
  475.  *                    out to the floppy using our isoWrite call.
  476.  *
  477.  ************************************************************************/
  478. OSErr
  479. CopyRsrcFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length)        /* how much to write */
  480. {
  481.     Ptr    rsrcBuf;
  482.     ParamBlockRec    pb;
  483.     Boolean        goOn;
  484.     OSErr        result;
  485.     long        physicalLength;
  486.     short        myRefNum;
  487.     
  488.     ClearOut((Ptr)&pb, sizeof(pb));
  489.     goOn = true;
  490.     physicalLength = ROUND_UP(length);
  491.     
  492.     rsrcBuf = NewPtrClear(physicalLength);
  493.     if (rsrcBuf == NULL)
  494.     {
  495.         ErrorMsg("Can't allocate %ld bytes for CopyRsrcFork()", length);
  496.         return mFulErr;    /* nothing to clean up */
  497.     }
  498.  
  499.     pb.ioParam.ioCompletion = NULL;
  500.     pb.ioParam.ioNamePtr = name;
  501.     pb.ioParam.ioVRefNum = vRefNum;
  502.     pb.ioParam.ioVersNum = 0;
  503.     pb.ioParam.ioPermssn = fsCurPerm;
  504.     pb.ioParam.ioMisc = NULL;
  505.     result = PBOpenRF(&pb, false);
  506.     if (result != noErr)
  507.     {
  508.         ErrorMsg("CopyRsrcFork: PBOpenRF returned %d", result);
  509.         ErrorMsg("vRefNum %d, name %P", vRefNum, name);
  510.         C2PStr((char *)name);
  511.         goOn = false;
  512.     }
  513.     
  514.     if (goOn)
  515.     {
  516.         myRefNum = pb.ioParam.ioRefNum;
  517.         result = FSRead(myRefNum, &length, rsrcBuf);
  518.         if (result != noErr)
  519.         {
  520.             ErrorMsg("CopyRsrcFork: FSRead returned %d", result);
  521.             goOn = false;
  522.         }
  523.     }
  524.     
  525.     if (goOn)
  526.     {
  527.         result = isoWrite(referenceNumber, rsrcBuf, physicalLength, start);
  528.  
  529.         if (result != noErr)
  530.         {
  531.             ErrorMsg("CopyRsrcFork: isoWrite returned %d", result);
  532.             goOn = false;
  533.         }
  534.     }
  535.         
  536.     PBClose(&pb, false);
  537.     DisposePtr(rsrcBuf);
  538.     return result;
  539. }
  540.  
  541.  
  542.  
  543. /************************************************************************
  544.  *
  545.  *  Function:        CopyDataFork
  546.  *
  547.  *  Purpose:        copy the resource fork of a file
  548.  *
  549.  *  Returns:        OSErr
  550.  *                        mostly noErr, but could be
  551.  *                        ioErr and the like if isoWrite complains.
  552.  *
  553.  *  Side Effects:    floppy gets new data written on it.
  554.  *
  555.  *  Description:    we have a starting location, "start", and a length.
  556.  *                    Allocate an appropriate buffer and read from the file
  557.  *                    specified by "name" and "vRefNum".  Write that information
  558.  *                    out to the floppy using our isoWrite call.
  559.  *
  560.  ************************************************************************/
  561. OSErr
  562. CopyDataFork(short referenceNumber, StringPtr name, short vRefNum, long start, long length)        /* how much to write */
  563. {
  564.     Ptr    dataBuf;
  565.     ParamBlockRec    pb;
  566.     Boolean        goOn;
  567.     OSErr        result;
  568.     long        physicalLength;
  569.     short        myRefNum;
  570.     
  571.     ClearOut((Ptr)&pb, sizeof(pb));
  572.     goOn = true;
  573.     physicalLength = ROUND_UP(length);
  574.     
  575.     dataBuf = NewPtrClear(physicalLength);
  576.     if (dataBuf == NULL)
  577.     {
  578.         ErrorMsg("Can't allocate %ld bytes for CopyDataFork()", length);
  579.         return mFulErr;    /* nothing to clean up */
  580.     }
  581.     
  582.     pb.ioParam.ioCompletion = NULL;
  583.     pb.ioParam.ioNamePtr = name;
  584.     pb.ioParam.ioVRefNum = vRefNum;
  585.     pb.ioParam.ioVersNum = 0;
  586.     pb.ioParam.ioPermssn = fsCurPerm;
  587.     pb.ioParam.ioMisc = NULL;
  588.     result = PBOpen(&pb, false);
  589.     if (result != noErr)
  590.     {
  591.         ErrorMsg("CopyDataFork: PBOpen returned %d", result);
  592.         ErrorMsg("vRefNum %d, name %P", vRefNum, name);
  593.         C2PStr((char *)name);
  594.         goOn = false;
  595.     }
  596.     
  597.     if (goOn)
  598.     {
  599.         myRefNum = pb.ioParam.ioRefNum;
  600.         result = FSRead(myRefNum, &length, dataBuf);
  601.         if (result != noErr)
  602.         {
  603.             ErrorMsg("CopyDataFork: FSRead returned %d", result);
  604.             goOn = false;
  605.         }
  606.     }
  607.     
  608.     if (goOn)
  609.     {
  610.         result = isoWrite(referenceNumber, dataBuf, physicalLength, start);
  611.  
  612.         if (result != noErr)
  613.         {
  614.             ErrorMsg("CopyDataFork: isoWrite returned %d", result);
  615.             goOn = false;
  616.         }
  617.     }
  618.     
  619.     PBClose(&pb, false);
  620.     DisposePtr(dataBuf);
  621.     return result;
  622. }
  623.  
  624. /************************************************************************
  625.  *
  626.  *  Function:        CreateFiles
  627.  *
  628.  *  Purpose:        create files in the root of a ISO floppy.
  629.  *    
  630.  *  Returns:        nothing
  631.  *
  632.  *  Side Effects:    floppy gets new data in famous root area
  633.  *
  634.  *  Description:    For each file, find the size of the two forks.
  635.  *                    Copy the resource fork first, then the data fork
  636.  *                    (associated files come before data files in ISO)
  637.  *
  638.  ************************************************************************/
  639. void
  640. CreateFiles(short referenceNumber)
  641. {
  642.     StringPtr    name;
  643.     short    vRefNum;
  644.     DirRcd    dirRcd;
  645.     long    start;        /* where we start putting data on the CD */
  646.     long    rsrcLength;
  647.     long    dataLength;
  648.     char    *b;
  649.     OSErr    result;
  650.     OSType    fType;
  651.     OSType    fCreator;
  652.     short    flags;
  653.     short    ISOFlags;
  654.     char    buffer[CDBLKSIZE];
  655.     
  656.     
  657.     ClearOut(buffer, sizeof(buffer));
  658.     b = &buffer[0];
  659.     name = (StringPtr)NewPtr(255);
  660.     if (name == NULL)
  661.     {
  662.         ErrorMsg("Can't allocate 255 bytes for a string.");
  663.         return;
  664.     }
  665.  
  666.     CreateDirRcd(&dirRcd, rootName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  667.     CopyDirRcdToBuffer(&dirRcd, b);
  668.     b += dirRcd.len_dr;
  669.  
  670.     CreateDirRcd(&dirRcd, parentName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  671.     CopyDirRcdToBuffer(&dirRcd, b);
  672.     b += dirRcd.len_dr;
  673.  
  674.     start = DATASTART * CDBLKSIZE;
  675.  
  676.     /* Keep asking for names, even if errors occur.  Most errors will be because
  677.      * The user tried to copy too big of a file to the floppy. 
  678.      */
  679.     while (HFSFile(name, &vRefNum) == true)
  680.     {
  681.         result = GetFileInfo(name, vRefNum, &rsrcLength, &dataLength, &fType, &fCreator, &flags);
  682.         if (result != noErr)
  683.             ErrorMsg("Can't get file information for %s", name);
  684.         else
  685.         {
  686.             ISOFlags = (flags & fInvisible) ? existenceBit : 0;
  687.     
  688.             if (rsrcLength != 0L)
  689.             {
  690.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, rsrcLength, ISOFlags | associatedBit,
  691.                     fType, fCreator, flags);
  692.     
  693.                 result = CopyRsrcFork(referenceNumber, name, vRefNum, start, rsrcLength);
  694.                 if (result == noErr)
  695.                 {
  696.                     CopyDirRcdToBuffer(&dirRcd, b);
  697.                     b += dirRcd.len_dr;
  698.                     start = ROUND_UP(start+rsrcLength);
  699.                 }
  700.                 else
  701.                     ErrorMsg("Failed to copy resource fork.");
  702.         
  703.             }
  704.     
  705.             if (result == noErr)
  706.             {
  707.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, dataLength, ISOFlags, 
  708.                     fType, fCreator, flags);
  709.         
  710.                 result = CopyDataFork(referenceNumber, name, vRefNum, start, dataLength);
  711.                 if (result == noErr)
  712.                 {
  713.                     CopyDirRcdToBuffer(&dirRcd, b);
  714.                     b += dirRcd.len_dr;
  715.                     start = ROUND_UP(start+dataLength);
  716.                 }
  717.                 else
  718.                     ErrorMsg("Failed to copy data fork.");
  719.         
  720.                 ClearOut((Ptr)name, 255);
  721.             }
  722.         }
  723.     }
  724.  
  725.     result = isoWrite(referenceNumber, (Ptr)buffer, (long)sizeof(buffer), (long) (DIRECTORY*CDBLKSIZE));
  726.     if (result != noErr)
  727.         ErrorMsg("CreateDataFiles: isoWrite of directory records returned %d", result);
  728.     DisposePtr((Ptr)name);
  729. }
  730.  
  731.